繼上篇我們得知如何運用Navigation在Fragment中做頁面切換。
而今天要講的是Safe Args,
他的作用是在Fragment中頁面切換時,傳遞參數(Arguments)。
首先要在app的build.gradle加入:
dependencies {
implementation("androidx.navigation:navigation-runtime-ktx:2.3.5")
implementation("androidx.navigation:navigation-fragment-ktx:2.3.5")
implementation("androidx.navigation:navigation-ui-ktx:2.3.5")
}
module層的build.gradle
apply plugin: "androidx.navigation.safeargs.kotlin"
我們將昨天的navigation.xml打開,會看到所有頁面。
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
app:startDestination="@id/aFragment"
android:id="@+id/nav_graph">
<fragment
android:id="@+id/aFragment"
android:name="com.example.cashdog.cashdog.AFragment"
android:label="@string/label_blank"
tools:layout="@layout/fragment_blank" >
<action
android:id="@+id/action_aFragment_to_bFragment"
app:destination="@id/bFragment" />
</fragment>
<fragment
android:id="@+id/bFragment"
android:name="com.example.cashdog.cashdog.BFragment"
android:label="@string/label_blank_2"
tools:layout="@layout/fragment_blank_fragment2" />
</navigation>
假設我們要從AFragment傳遞參至BFragment,
會在BFragment底下加入:
<argument
android:name="userName"
app:argType="string"
app:nullable="false"/>
android:name: 可以視為argument的idapp:nullable: AFragment頁面轉到BFragment時,是否為必傳值。false為必填,true可不填。app:argType: argument的型態。app:argType能選擇的類型有:
加入navigation.xml中,會像這樣:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
app:startDestination="@id/aFragment"
android:id="@+id/nav_graph">
<fragment
android:id="@+id/aFragment"
android:name="com.example.cashdog.cashdog.AFragment"
android:label="@string/label_blank"
tools:layout="@layout/fragment_blank" >
<action
android:id="@+id/action_aFragment_to_bFragment"
app:destination="@id/bFragment" />
</fragment>
<fragment
android:id="@+id/bFragment"
android:name="com.example.cashdog.cashdog.BFragment"
android:label="@string/label_blank_2"
tools:layout="@layout/fragment_blank_fragment2">
<argument
android:name="userName"
app:argType="string"
app:nullable="false"/>
</fragment>
</navigation>
args的方式直接將要傳遞的參數寫入actionAFragmentToBFragment(argument)中,
val action = AFragmentDirections.actionAFragmentToBFragment(userName)
class AFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.findViewById<Button>(R.id.next)
.setOnClickListener {
val action = AFragmentDirections.actionAFragmentToBFragment(userName)
view.findNavController().navigate(action)
}
}
}
args的方式 - by navArgs在BFragment中取得傳遞過來的argument包裹:
val args by navArgs<BFragmentArgs>()
直接獲取argument中的內容方式如下:
val userName = args.userName
class BFragment : Fragment() {
private val args by navArgs<BFragmentArgs>()
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val userName = args.userName
}
...
}
比起以前的寫法相較快很多:
val userName = arguments?.getString("userName") ?: ""
參考: